home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
help10.arc
/
HELP.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-03-06
|
11KB
|
300 lines
page 60,132
; HELP.COM by Bob Montgomery, 2/23/87
; This program is a generic help screen template for use with the MASM
; assembler. The desired help message is written as db's at Hlpst in
; place of the test message that is there now. The only restrictions
; on the help message are:
; 1. The message must not exceed 80 characters wide.
; 2. The message must not exceed 25 lines long.
; 3. Each help line must be the same length.
; The program will auto center the message on the display screen. The hot
; key combo to bring up the help screen is defined as Hotkey below (set
; for Cntl-Leftshift right now) and can be changed to another combination
; by changing the equate for Hotkey.
Code segment
assume cs:Code,ds:Code
org 100h
Begin: jmp Init ;Initialize program
Esc equ 1Bh
Vidmem equ 0B800h ;Location of screen 0
Monomem equ 0B000h ;Location of mono screen
BWattr equ 70h ;Grey background, black foreground
; Bits in shift status
Rtsh equ 1
Lftsh equ 2
Cntl equ 4
Alt equ 8
Scrl equ 10h
Numl equ 20h
Capl equ 40h
Mode db ? ;Current video mode
Vpage db ? ;Current video page
Vidseg dw ? ;Current page segment
Hlpflg db 0 ;1 => Help on
Attr db ? ;Attribute to use
Cursor dw ? ;Current cursor type
; ==================================================================
; This is the test help message to be displayed on the video screen.
; Change this area for your own help message, color, and hot key combo.
Colattr equ 4Eh ;Red background, yellow foreground
Hotkey equ Cntl+Lftsh ;Define the hot key combo to bring up screen
Hlpst: db 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
Linchr equ $-Hlpst ;Chars on each help line
db 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
db 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'
db 'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD'
db 'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE'
DB 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'
db 'GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG'
db 'HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'
db 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'
db 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ'
db 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'
DB 'LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL'
DB 'MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM'
DB 'NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN'
DB 'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO'
DB 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP'
DB 'QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ'
DB 'RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR'
DB 'SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'
DB 'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT'
DB 'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU'
DB 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
DB 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW'
; ===================================================================
Msglen equ $-Hlpst ;# chars in help buffer
Lines equ Msglen/Linchr ;# lines of help
Buflen equ 2*Msglen ;Screen data buffer length
Stlin equ (25-Lines)/2 ;Start line
Stchr equ (80-Linchr)/2 ;Start byte on line
Stscr equ 160*Stlin + 2*Stchr ;Start of mem to put help
Scrbuf: db Buflen dup (?) ;Buffer for screen data
; New Int 9 routine - check for Cntrl-LShift; ignore others.
; Since Int 9 is called every time a key is pressed or released, and
; reads the keyboard thru some mysterious means in BIOS, we must call
; the old Int 9 as a subroutine each time an Int 9 is generated. But,
; an interrupt routine has a IRET instead of a RET as the return
; instruction, which pops the return address like a RET does, and then
; pops the flags. So to call Int 9 like a subroutine, we have to push
; the flags first; then when the the IRET is executed, control returns
; to our program with the stack pointer at the right place.
Start: push ax ;Save all for calling program
push bx
push cx
push dx
push ds
push es
push di
push si
pushf ;Put flags on stack since Int pops flags
;Call old Int 9 to get key-will pop flags
db 9Ah ;Opcode for far call
Oldint dw ?,? ;Save old Int 9 vector here
mov ah,2 ;Get shift status
Int 16h ;in al
and al,Hotkey ;Only keep Hot keys
cmp al,Hotkey ;Were both pressed?
jne Exit ;No
push cs
pop ds ;Yes, set ds=cs
cmp Hlpflg,1 ;Is help already up?
jne Go ;No, put it up
; If help is already up, ignore the Hotkey.
Exit: pop si ;Restore all for calling program
pop di
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
iret ;Pop return address and flags
; Come here if should put up help.
Go: mov al,Colattr ;Assume color
mov Attr,al
mov ah,15 ;Get video mode in al
int 10h ;and page in bh
mov Mode,al ;Save Mode
mov Vpage,bh ;and page
cmp al,2 ;Mode=2?
je Color ;Yes
cmp al,3 ;Mode=3?
je Color ;Yes
cmp al,7 ;Mode=7? (mono)
jne Exit ;No, must be graphics so exit
mov al,BWattr ;Set B&W attribute
mov Attr,al
mov bx,Monomem ;and start of mono video memory
jmp short A0
Color: mov bl,0 ;Bx=256*display page
add bx,Vidmem ;Get display mem segment
A0: mov ds,bx ;in ds
; Put up help screen.
; First save current screen to buffer.
call Hidecur ;Hide cursor
call Vidoff ;Disable video (avoids snow on CGA)
mov dl,Lines ;Get # lines of help
push cs ;es=cs
pop es
mov si,Stscr ;ds:si points to help screen area in disp mem
mov di,offset Scrbuf ;es:di points to buffer for screen data
push si ;Save them
push es
push ds
mov ch,0 ;ch=0
mov cl,Linchr ;cx=chars/help line
A1: push si ;Save position in scrn mem & chars/line
push cx
cld ;Set to inc si & di
rep movsw ;Move screen to buffer
pop cx ;Get start of line & chars/line
pop si
add si,160 ;Next line, same column
dec dl ;Done all lines?
jne A1 ;No
; Now put up help.
pop es ;Now ds=cs, es:di=help scrn area in screen mem
pop ds
pop di
push di ;Put back in orig order
push ds
push es
mov si,offset Hlpst ;Point si to help data
mov dl,Lines ;Get chars/help line
mov ah,Attr ;Get char attribute (color)
B1: push di ;Save disp mem pos & chars/help line
push cx
B2: lodsb ;Get a help char in al
stosw ;Save char & attribute in screen mem
loop B2 ;Do whole line
pop cx ;Get start of disp line & chars/line
pop di
add di,160 ;Next line, same column
dec dl ;Done all lines?
jne B1 ;No
mov Hlpflg,1 ;Yes, indicate help up
call Vidon ;and enable video
; Now, wait for the escape key; come here after each keypress (Int 9).
Wait1: mov ah,0 ;Wait for a key
int 16h
cmp al,Esc ;Was it Escape?
jne Wait1 ;No
; If Esc was pressed, put the old screen back
pop es ;ds=cs; es:di=start of help area in disp mem
pop ds
pop di
mov si,offset Scrbuf ;Point to old screen data buffer
call Vidoff ;Disable video (avoid snow on CGA)
mov dl,Lines ;Chars/help line
C1: push di ;Save scrn mem pointer & chars/line
push cx
rep movsw ;Move a line to scrn mem
pop cx ;Get start of line & chars/line
pop di
add di,160 ;Next line, same column
dec dl ;Done all lines?
jne C1 ;No
mov Hlpflg,0 ;Yes, clear flag
call Vidon ;Enable video
call Showcur ;Turn cursor back on
jmp Exit ;and return
; Sub to turn cursor off; come with ds=video.
Hidecur: push cx
push ds
push cs ;ds=cs
pop ds
mov ah,3 ;Get current cursor data
mov bh,Vpage ;for current page
int 10h
mov Cursor,cx ;Save cursor type
mov ch,20h ;Set cursor off
mov ah,1
int 10h
pop ds
pop cx
ret
; Sub to turn cursor on; come with ds=cs.
Showcur: mov cx,Cursor ;Set original cursor Type
mov bh,Vpage
mov ah,1
int 10h
ret
; Turn video off
Vidoff: cmp cs:Mode,7 ;Mono?
je D0 ;Yes, skip wait for vert retrace
push ds
push dx
push ax
call Getmode ;Get current video mode byte
and al,0F7h ;Clear video enable bit
out dx,al ;Send to mode control port
pop ax
pop dx
pop ds
D0: ret
; Turn video on
Vidon: cmp cs:Mode,7 ;Mono?
je E0 ;Yes, skip wait for vert retrace
push ds
push dx
push ax
call Getmode ;Get current video mode byte
or al,8 ;Set video enable bit
out dx,al ;Send to mode control port
pop ax
pop dx
pop ds
E0: ret
; Sub to wait for vertical retrace to avoid snow on CGA screen.
Vert: mov dx,3DAh ;CRT status port
F1: in al,dx ;Read status
test al,8 ;Vert retrace?
je F1 ;No
mov dx,3D8h ;Point to video mode port
ret ;Yes, return
Getmode: call Vert ;Wait for vert retrace
mov ax,40h ;Get video mode
mov ds,ax ;at 465h
mov al,ds:[65h]
ret ;and return
; Come here to install the program as the new Int 9 routine.
Init: mov ax,3509h ;Get current Int 9 vector
int 21h ;in es:bx
push cs
pop ds
mov Oldint,bx ;Save it
mov Oldint+2,es
mov ax,2509h ;Set new Int 9 routine
mov dx,offset Start
int 21h
mov dx,offset Init ;Terminate and
int 27h ;stay resident
Code ends
end Begin